/* geocoding functions */
var serviceUrl = "";
var maxZoom = 15; // 19 is closest zoom, 1 is furthest
var minZoom = 12; // 19 is closest zoom, 1 is furthest
var noLocations = "No results returned. Please try another location.";


/** GEOCODING AND AREA COMPUTING FUNCTIONS **/

/** 
 *  Parses an address string inputted by the user.
 *  @param {String} address - This holds the address string inputted by the user.
 */
function searchByAddress( address ) {
  var geocoder = new google.maps.Geocoder();
  // get geocoded point for address
  geocoder.geocode( { 'address': address }, getAddressPoint);
}

/** 
 *  Handles the output from the GClientGeocoder attempting to parse address strings into geolocations.
 *  @param {google.maps.GeocoderStatus} status - Shows status of search (successful or otherwise).
 *  @param {google.maps.GeocodeResults} results - A JSON object representing the results from the geocoder.
 */
function getAddressPoint( results, status ) {
  if ( status == google.maps.GeocoderStatus.OK ) {
    // sets the location in preferences
    setLocation(results[0].geometry.location);
    // retrieves the search area and calls the webservice
    getAreaForZoom( maxZoom, "includeMoreResults" );
  } else {
    showMessage( noLocations );
  }
}

/**
 *  Retrives search area for zoom level, sets zoom preference and calls getResults.
 *  @param {int} zoom - Zoom level to search on.
 *  @param {string} callback - call
 */
function getAreaForZoom( zoom, callback ) {
  // set zoom preference
  setZoom( zoom );
  // retrieve search area
  bounds = getSearchArea( getLocation(), getZoom() );
  // call webservice
  getResults( getFuelType(), callback );
}

/**
 *  Widen geopoints to give a search area.
 *  @param {google.maps.LatLng} location - Geocoded point of search.
 *  @returns {google.maps.LatLngBounds} bounds - Rectangle of search area.
 */
function getSearchArea( location, zoom )
{
  // the horizontal and vertical padding to get a search area.
  var hpad = ( 0.00174611807 / 2 ) * Math.pow( 2, 20 - zoom );
  var vpad = ( 0.00089762265 / 2 ) * Math.pow( 2, 20 - zoom );
    
  var southWest = new google.maps.LatLng(location.lat() - vpad, location.lng() - hpad);
  var northEast = new google.maps.LatLng(location.lat() + vpad, location.lng() + hpad);
  
  return new google.maps.LatLngBounds(southWest, northEast);
}






/** WEB SERVICE CALLS **/

/**
 *	Retrieves results from webservice.
 * 	@param {int} fueltype - fuel type to search for.
 *  @param {string} callback - string representing which function to call on callback.
 * 	@reference {google.maps.LatLngBounds} bounds - global variable that holds the latest bounds for search.
 */
function getResults( fueltype, callback ) {
  // Decommissioned.
  return;
}

/**
 *  A wrapper to include more zoom levels for initial searches.
 */
function includeMoreResults( data ) {
  // if no results have been returned and the zoom level is not the minimum
  if ( ( data.ResultData.ResultCode != '0' ) && ( getZoom() > minZoom ) ) {
    // zoom out and search again
    getAreaForZoom( getZoom() - 1, "includeMoreResults" );
  } else {
    populateResults( data );
  }
}

/**
 *  Takes JSON-parsed results from the MM webservice and populates them into the results panel.
 *  @param {array} data - JSON-parsed results from the MM webservice.
 */
function populateResults( data )
{
  // Decommissions.
  return;
}






/** UI FUNCTIONS **/

/**
 *  Initialises the search box's placeholder text and removes its overflow.
 */
function loadSearchBox() {
  // generate placeholder text for all browsers.
  if (prefs.getString("address") == "") {
    $.placeholder.shim();
  }
  $( "window" ).css( "overflow-x", "hidden" );
  $( "window" ).css( "overflow-y", "none" );
}

/**
 *  Display a message saying there are no sites for this location.
 */
function throwNoLocationsMessage() {
  if ( getViewName() == 'canvas' ) { map.clearMarkers(); }
  // show message saying there are no results
  showMessage( noLocations );
  return;
}






/** GADGET-SPECIFIC FUNCTIONS **/

/**
 *  Retrieve the current view name.
 */
function getViewName() {
  return gadgets.views.getCurrentView().getName();
}

/**
 * 	Sets the address preference in the gadget to the last searched entity 
 */
function usePrefs() {
  $( "#address" ).val(getAddress());
  $( "#fueltypes" ).val(getFuelType()).attr('selected', true);
}






/** COMMON RESULTS FUNCTIONS **/

/**
 *  Displays message in results pane.
 *  @param {String} message - 
 */
function showMessage( message ) {  
  // set inner html
  results.html( "<p class=message>" + message + "</p>" );
  
  showHideResultElements( true );
}

/**
 *  Remove the results from the page and returns to pre-search appearance.
 */
function clearResults() {
  $( ".resultsPanel" ).empty();
  if (getViewName() == 'canvas') {
  	showMessage( "Please search again." );
    clearMap();
  } else {
  	showHideResultElements(false);
	showHideGoogleAd(true);
  }
}





/** PREFERENCES GETTERS AND SETTERS **/

/**
 *  Retrieves location from prefs.
 *  @returns {google.maps.LatLng} location - geocoded point of searched address stored in prefs. 
 */
function getLocation() {
  var location = new google.maps.LatLng(prefs.getString("lat"), prefs.getString("long"));
  return location;
}

/**
 *  Sets the geocoded location in the preferences
 *  @param {google.maps.LatLng} location - geocoded point of searched address.
 */
function setLocation( location ) {
  // set the coordinates in the preferences
  prefs.set("lat", location.lat().toString());
  prefs.set("long", location.lng().toString());  
}

/**
 *  Retrieves zoom from prefs.
 *  @returns {int} zoom - searched zoom stored in prefs. 
 */
function getZoom() {
  return prefs.getString("zoom") * 1;
}

/**
 *  Sets the searched zoom in the preferences
 *  @param {int} zoom - searched zoom.
 */
function setZoom( zoom ) {
  prefs.set("zoom", zoom.toString());  
}

/**
 *  Retrieves address from preferences.
 *  @returns {string} address - address stored in prefs
 */
function getAddress() {
  return $('<div></div>').html(prefs.getString("address")).text().toString();
}

/**
 *  Sets the searched address in the preferences.
 *  @param {string} address - address stored in prefs
 */
function setAddress( address ) {
  prefs.set("address", address);
}

/**
 *  Retrieves fuel type from preferences.
 *  @returns {int} fueltype - searched fuel type in prefs
 */
function getFuelType() {
  return prefs.getString("fueltype") * 1;
}

/**
 *  Sets the fuel type in the preferences.
 *  @param {int} fueltype - searched fuel type in prefs
 */
function setFuelType( fueltype ) {
  prefs.set("fueltype", fueltype.toString());
}
